package com.media.selector

import android.content.Intent
import android.net.Uri
import androidx.annotation.Nullable
import androidx.fragment.app.FragmentActivity
import com.media.selector.camera.CameraActivity
import com.media.selector.media.helper.SelectionCreator
import com.media.selector.media.listener.OnMediaSelectorResultCallbacks
import com.media.selector.media.loader.IMediaSelecterLoader
import com.media.selector.media.loader.MediaProxyLoader
import com.media.selector.media.model.entity.MimeType

/**
 * date        ：2020/5/11
 * author      ：蒙景博
 * description ：
 */
class MediaSelector private constructor() {

    companion object {
        /**
         * 拍照
         */
        const val TAKE_PHOTO_REQUEST_CODE = 1000
        const val EXTRA_TAKE_PHOTO_STATE = "extra_take_photo_state"
        const val EXTRA_TAKE_PHOTO_RESULT = "extra_take_photo_result"

        /**
         * 选中的结果集合
         */
        const val MEDIA_SELECT_REQUEST_CODE = 1001
        const val EXTRA_RESULT_SELECTION = "extra_result_selection"
        const val EXTRA_RESULT_SELECTION_PATH = "extra_result_selection_path"

        @Volatile
        private var INSTANCE: MediaSelector? = null
        fun with(): MediaSelector = INSTANCE ?: synchronized(this) { MediaSelector().also { INSTANCE = it } }
    }

    private var mProxyLoader: MediaProxyLoader? = null

    fun init(loader: IMediaSelecterLoader) {
        this.mProxyLoader = MediaProxyLoader(loader)
    }

    /**
     * MIME types the selection constrains on.
     *
     *
     * Types not included in the set will still be shown in the grid but can't be chosen.
     *
     * @param mimeTypes MIME types set user can choose from.
     * @return [SelectionCreator] to build select specifications.
     * @see MimeType
     *
     * @see SelectionCreator
     */
    fun choose(mimeTypes: Set<MimeType>): SelectionCreator {
        return SelectionCreator(mimeTypes)
    }

    fun onMediaSelectorResult(requestCode: Int, @Nullable data: Intent?, callback: OnMediaSelectorResultCallbacks) {
        if (requestCode == TAKE_PHOTO_REQUEST_CODE) {
            callback.onTakePhotoResult(obtainTakePhotoPathState(data), obtainTakePhotoPathResult(data))
        } else if (requestCode == MEDIA_SELECT_REQUEST_CODE){
            callback.onMediaSelectorResult(obtainUriResult(data), obtainPathResult(data))
        }
    }

    /**
     * 拍照状态：true:拍照成功，false:拍照失败
     */
    private fun obtainTakePhotoPathState(data: Intent?): Boolean {
        return data?.getBooleanExtra(EXTRA_TAKE_PHOTO_STATE, false) ?: false
    }

    /**
     * 获取用户选拍照的 path
     */
    private fun obtainTakePhotoPathResult(@Nullable data: Intent?): String? {
        return  if (data?.hasExtra(EXTRA_TAKE_PHOTO_RESULT) == true) data.getStringExtra(
            EXTRA_TAKE_PHOTO_RESULT
        ) else null
    }

    /**
     * 获取用户选择的媒体的 Uri list.
     */
    private fun obtainUriResult(@Nullable data: Intent?): List<Uri>? {
        return data?.getParcelableArrayListExtra(EXTRA_RESULT_SELECTION)
    }

    /**
     * 获取用户选择的媒体的 Path list.
     */
    private fun obtainPathResult(@Nullable data: Intent?): List<String>? {
        return data?.getStringArrayListExtra(EXTRA_RESULT_SELECTION_PATH)
    }

    fun takePhoto(@Nullable activity: FragmentActivity?) {
        activity?.startActivityForResult(Intent(activity, CameraActivity::class.java), TAKE_PHOTO_REQUEST_CODE)
    }

    fun load(@Nullable uri: Uri?): MediaProxyLoader? = mProxyLoader?.load(uri)
}